home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 60.zip
/
BS1 part 60
/
Kick Pascal v2.10 d2.adf
/
DEMO
/
Datei.p
< prev
next >
Wrap
Text File
|
1990-11-01
|
13KB
|
485 lines
Program AddrMat;
{ Eine kleine Adressdatei. }
{ }
{ Geschrieben von : }
{ Jens "Himpel" Gelhar 1989 }
{ als Demo für Himpel-/Kickpascal }
{ Dieses Programm demonstriert u. a. die Ein-/Ausgabeoperationen.
Um die Anwendung der Dateibefehle zu zeigen, wird die Datei
nicht in den Speicher geladen, sondern ausschließlich auf der
Disk bearbeitet. Dies schränkt die Möglichkeiten des Programms
natürlich stark ein. }
Label Ende1;
{ Labels sollten nur verwendet werden, wenn der "normale"
Programmablauf unterbrochen wird. Das Label 'Ende1' steht
kurz vor dem Ende des Hauptprogramms und wird angesprungen,
wenn bei der Eingabe des Dateinamens ESC gedrückt wird. }
Const
CSI = chr($9b); { Steuersequenzen-Einleiter }
CrsrUp = chr(1); { Da bei Betätigung der Cursortasten }
CrsrDown = chr(2); { ganze Escape-Sequenzen gesendet werden, die }
CrsrLeft = chr(3); { umständlich zu handhaben sind, werden sie }
CrsrRigth= chr(4); { von der GETKEY-Prozedur in diese Codes gewandelt. }
BackSpace= chr(8);
LF = chr(10);
CR = chr(13);
Esc = chr(27);
Del = chr($7f);
Type
Anrede = (Herr, Frau, Firma, Ungueltig);
Person=Record { der Hauptdatentyp }
Anr: Anrede;
VName,NName: String[30]
Telefon: String[20]
Strasse: String[30]
Hausnr: integer
Plz: 0..9999
Ort: String[12];
End;
Datei = File of Person;
StrTyp = String; { Für Parameterübergaben. Denn: "String" ist }
{ kein Typbezeichner, sondern ein Symbol! }
Var
fname: StrTyp; { Dateiname }
f: Datei; { die Datei }
fs: Long; { Speicher für "filesize(f)" }
Menu: Char; { Im Hauptmenü eingegebenes Zeichen }
Win, Con: Ptr; { Windowhandle und Console-Device }
Out: String; { Ausgabepuffer für "WriteCon" }
Procedure WriteC(s: Str);
{ String "s" über Console.device ausgeben }
Begin
WriteCon(con,s)
End;
Procedure SetXY(x,y: integer);
{ GotoXY-Ersatz für ConDevice }
Var h: String;
Begin
h := CSI + IntStr(y) + ';' + intStr(x) + 'H';
WriteCon(Con,h)
End;
Function WaitKey: Char;
{ Auf Tastencode warten und zurückgeben }
Var c: Char;
Sig: Long;
Begin
Repeat
c := ReadCon(Con);
If c = #0 Then Sig := Wait(-1)
Until c <> chr(0);
WaitKey := c
End;
Function GetKey: Char;
{ Taste lesen und Sequenzen wandeln }
Var c: Char;
Procedure CSIHandler;
Var s: String;
Begin
s:='';
Repeat { Sequenz zeichenweise lesen }
s:=s+WaitKey
Until (Length(s)>=50) or ( s[Length(s)] >= '@');
If s='A' Then GetKey := CrsrUp Else
If s='B' Then GetKey := CrsrDown Else
If s='C' Then GetKey := CrsrRigth Else
If s='D' Then GetKey := CrsrLeft Else
GetKey := chr(0)
End;
Begin
c := WaitKey;
If c in [ chr(32).. chr(126), chr(160)..chr(255) ] Then
GetKey := c { druckbares Zeichen }
Else
Case c Of
chr(8): GetKey := BackSpace;
chr(13): GetKey := CR;
chr(27): GetKey := Esc;
chr($7f):GetKey := Del;
CSI: CSIHandler;
Otherwise
Getkey := chr(0)
End;
End;
Procedure FindEnd( Var st: StrTyp, i: integer);
{ Ende von s[1] .. s[i] suchen, mit Nullbyte markieren }
Begin
While (i>1) and (st[i]=' ') Do
i:=pred(i);
st[ i + ord(st[i]<>' ') ] := chr(0)
End;
Function LinEd( Var s: Strtyp, x0,y0,max: integer, Var x: integer): Char;
{ String "s" mit der Höchstlänge "max" an Position (x0,y0) edieren. }
{ x: Cursorposition innerhalb Zeile. }
{ zurückgeben: letztes eingegebenes Zeichen (CR, Esc oder Up/Down }
Var i: integer;
c: Char;
ende: Boolean;
Begin
SetXY(x0, y0); { an angegebener Position... }
writec(s); { String ausgeben und... }
writec(#e'K'); { Rest der Zeile löschen. }
For i:=Length(s)+1 to max Do
s[i]:=' '; { String mit Spaces auffüllen }
s[max+1] := chr(0); { ...und mit Nullbyte abschließen. }
SetXY(x0+x-1, y0);
ende := false;
Repeat { Zeileneditor-Hauptschleife }
c := GetKey;
If c in [chr(32)..chr(126), chr(160)..chr(255) ] Then
If x < max Then
Begin
For i:=max DownTo x+1 do { Platz machen }
s[i] := s[i-1];
s[x] := c; { und Zeichen einfügen. }
x := x+1;
writecon(con, #e'@'); { Ein Zeichen auf Bildschirm einfügen }
writecon(con, c) { und Zeichen ausgeben. }
End
Else
Else { kein darstellbares Zeichen }
Case c Of
CR, Esc, CrsrUp, CrsrDown: { mit diesen Tasten wird der }
Ende := true; { Editor verlassen. }
BackSpace:If x>1 Then
Begin
x:=pred(x);
For i:=x to max-1 do s[i] := s[i+1];
s[max]:=' ';
writecon(con, #8\e'P')
End;
CrsrLeft: If x>1 Then
Begin
x := pred(x);
writecon(con, #e'D')
End;
CrsrRigth: If x<max Then
Begin
x := succ(x);
writecon(con, #e'C')
End;
Del: Begin
For i:=x to max-1 do s[i] := s[i+1];
s[max]:=' ';
writecon(con, #e'P')
End;
Otherwise End;
Until ende;
FindEnd( s , max); { Spaces am zeilenende abschneiden }
LinEd := c { Zeichen zurückgeben }
End;
Procedure Ausgabe1(p: Person);
{ mit Feldnamen ausgeben }
Var s:String;
Begin
With p do
Begin
WriteC('Anrede: (HFG) ');
Case Anr Of
Herr: WriteC("Herr");
Frau: WriteC("Frau");
Firma: WriteC("Firma")
Otherwise End;
WriteC(#e'K'\10'Vorname: '); If Anr<>Firma Then WriteC(VName);
WriteC(#e'K'\10'Nachname: '); writeC(NName);
WriteC(#e'K'\10'Telefon: '); writeC(Telefon);
WriteC(#e'K'\10'Strasse: '); writeC(Strasse);
WriteC(#e'K'\10'Nr.: '); s := IntStr(HausNr); If HausNr>=0 Then writeC(s);
WriteC(#e'K'\10'Plz.: '); s := IntStr(Plz); If plz<>0 Then writeC(s);
WriteC(#e'K'\10'Ort: '); writeC(Ort);
End
End;
Procedure Edit(Var p:Person);
Var buf: String;
Zeile: integer;
z,s,m: integer;
c: Char;
Begin
SetXY(1,4);
Ausgabe1(p);
Zeile:=1;
Repeat
If Zeile=1 Then
Repeat
SetXY(16,4);
Case p.Anr Of
Herr: writeC("Herr");
Frau: writeC("Frau");
Firma: writeC("Firma");
Otherwise
End;
writeC(#e"K");
Repeat
c:=GetKey
Until Upcase(c) in ["H","F","G",CR,CrsrUp,CrsrDown,Esc];
Case Upcase(c) Of
"H": p.Anr := Herr;
"F": p.Anr := Frau;
"G": p.Anr := Firma;
Otherwise;
End;
Until (c in [CR, CrsrUp, CrsrDown, Esc]) and (p.Anr<>Ungueltig)
Else
If (Zeile=2) and (p.Anr=Firma) Then
Begin p.VName :=""; SetXY(16,5); writeC(#e'K') End
Else
Begin
With p Do
Case Zeile Of
2: Begin z:=29; buf:=VName End;
3: Begin z:=29; buf:=NName End;
4: Begin z:=19; buf:=Telefon End;
5: Begin z:=29; buf:=Strasse End;
6: Begin z:=20;
If HausNr<0 Then buf:='' Else buf:=IntStr(HausNr) End;
7: Begin z:=20;
If Plz<=0 Then buf:='' Else buf:=IntStr(plz) End;
8: Begin z:=11; buf:=Ort End;
End;
s:=1;
Repeat
c:=LinEd(buf,16,Zeile+3,z,s);
If (Zeile=6) and (buf<>'') Then
Begin
Val(buf,p.HausNr,m);
If (m<>0) or (p.HausNr<0) Then c:=" "
End;
If (Zeile=7) and (buf<>'') Then
Begin
Val(buf,p.Plz,m);
If (m<>0) or (p.Plz<1000) or (p.Plz>9999) Then c:=" "
End;
Until c in [CR, CrsrUp, CrsrDown, Esc];
With p Do
Case Zeile Of
2: VName:=buf;
3: Nname:=buf;
4: Telefon:=buf;
5: Strasse:=buf;
8: Ort:=buf
Else
End;
End;
If c in [cr, CrsrDown] Then Zeile:=Zeile+1
Else
If c=CrsrUp Then Zeile:=Zeile-1;
Until (Zeile=9) or (Zeile=0) or (c=Esc);
writeC(LF)
End;
Procedure Eingabe(Var p: Person);
Begin
WriteC(#12#10'Bitte Daten eingeben!'#10#10);
With p do
Begin
Anr := UnGueltig;
VName := "";
NName := "";
Telefon := "";
Strasse := "";
HausNr := -1;
Plz := 0;
Ort := "";
End;
Edit(p)
End;
Procedure Ausgabe(p: Person);
Var s: string[1000];
Begin
With p DO
Begin
Case Anr of
Herr: s := 'Herr '+VName
Frau: s := 'Frau '+VName
Firma:s := 'Firma '
Otherwise
error('Datenfehler!!');
End;
s := LF + s + " " + NName + LF + 'Tel. ' + Telefon + LF + Strasse
+ ' ' + IntStr(HausNR) + LF + IntStr(plz) + ' ' + Ort;
writecon(con,s);
End
End;
Procedure Ergänzen;
Var per: Person;
Begin
If Filepos(f)<>Filesize(f) Then
Seek(f,Filesize(f));
Eingabe(Per);
write(f,Per)
End;
Procedure Blättern;
Var per: Person;
i: Long;
c: Char;
Begin
i := 0;
Repeat
writeC(LF);
Seek(f,i);
read(f,per);
Out := #12#10"Datensatz Nr. " + IntStr(i+1);
If eof(f) Then Out := Out + " - Dateiende";
Out := Out + LF + LF;
WriteC(Out);
Ausgabe1(per);
writeC(#10\10'SPACE=weiter BACKSPACE=zurück RETURN=Edit ESC=Ende : ');
Repeat
c := GetKey
Until c in [" ",Esc,BackSpace,CR];
Case c Of
" ": If i<filesize(f) Then i:=i+1;
BackSpace: If i>0 Then i:=i-1;
CR: Begin SetXY(1,2); WriteC("Edit"\e"K"); Edit(per);
Seek(f,i); write(f,per)
End;
Otherwise
End;
Until (c=Esc) or (i=Filesize(f))
End;
Procedure DateiAusgeben;
Var p1,p2: Person; c:Char; i: integer;
Begin
Seek(f,0);
While not eof(f) Do
Begin
read(f,p1); { get(f); p1:=f^ }
Ausgabe(p1);
i:=i+1;
writecon(con,LF)
End;
writecon(con,#10'Bitte Taste drücken! ');
While ReadCon(con)<>chr(0) do ; { "Tastenpuffer" leeren }
c := GetKey
End;
Procedure Dateiname;
Var c: Char;
L: integer;
x: integer;
OK: Boolean;
Begin
Repeat
x := 1;
fname := '';
SetXY(1,2);
writecon(con,'Dateiname: ');
Repeat
c:=LinEd(fname,12,2,60,x)
Until ((fname<>'') and (c=CR)) or (c=Esc);
If c=Esc Then Goto Ende1;
WriteCon(con,LF);
L := Length(fname);
If L > 4 Then
If fname[L-3]<>'.' Then
fname:=fname+'.dat';
reset(f,fname);
If IOResult=0 Then
Exit
Else
Begin
Out := (LF+LF+'Datei '+fname+' existiert nicht.'$a$a'Anlegen? ');
WriteCon(Con, Out);
Repeat
c := GetKey
Until c in ["J","j","N","n"];
If Upcase(c)="J" Then
Begin
Rewrite(f,fname);
If IOResult<>0 Then
WriteCon(Con, #$0a$0a'Datei konnte nicht angelegt werden.')
Else
Begin
Close(f);
Reset(f,fname);
Exit
End
End
End
Until false
End;
Begin { Main }
Win:=Open_Window(0,0,640,200,1,0,$1006,'Himpels very special Database',Nil,640,200,640,255);
Con:=OpenConsole(Win);
Dateiname;
Repeat
fs := Filesize(f);
WriteCon(con,chr(12)); { Bildschirm löschen }
Case fs of
0: writecon(con, 'Datei ist leer.');
1: writecon(con, 'Datei enthält einen Datensatz');
Otherwise
Out:='Datei enthält '+IntStr(fs)+' Datensätze';
writecon(con, Out)
End;
writecon(con,''\10\10\&
\e'33mA'\e'31m Daten hinzufügen'\10\&
\e'33mB'\e'31m Blättern'\10\&
\e'33mL'\e'31m Adressliste ausgeben'\10\&
\e'33mQ'\e'31m Programmende'\10\10'--> ');
Menu:=GetKey;
Case Upcase(Menu) Of
'A': Ergänzen;
'B': Blättern;
'L': DateiAusgeben;
Otherwise ;
End;
Until Upcase(Menu) = 'Q';
writecon(con,#10#10'Tschüß!');
Close(f);
Ende1:
CloseConsole(Con);
Close_Window(Win);
End.